package com.sc.nft.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.*;
import com.sc.nft.sup.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * 服务接口实现
 *
 * @author rdg
 * @since 2022-06-09 17:05:25
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class AirdropGrantRecordServiceImpl implements AirdropGrantRecordService {
    private final AirdropGrantRecordDao airdropGrantRecordDao;
    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;
    private final ProductStockService productStockService;
    private final UserCollectionService userCollectionService;
    private final BoxItemService boxItemService;
    private final BoxProductDao boxProductDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final UserInfoDao userInfoDao;
    private final EquityPropsService equityPropsService;
    private final UserEquityPropsService userEquityPropsService;
    private final UserConsensusService userConsensusService;

    @Override
    public Page<AirdropGrantRecordVO> airdropGrantRecordList(int pageNo, int pageSize, String nickName, String userTel, String userUuid, String productUuid, String firstTitle, Integer typeClassify) {
        return airdropGrantRecordDao.airdropGrantRecordList(pageNo,pageSize,nickName,userTel,userUuid,productUuid,firstTitle,typeClassify);
    }

    @Override
    public List<AirdropGrantRecordExportListVO> airdropGrantRecordListExport(String collectionName, Date startTime, Date endTime) {
        List<AirdropGrantRecordExportListVO> airdropGrantRecordExportListVOS = airdropGrantRecordDao.airdropGrantRecordListExport(collectionName, startTime, endTime);
        airdropGrantRecordExportListVOS.forEach(airdropGrantRecordExportListVO -> {
            airdropGrantRecordExportListVO.setTypeClassifyName(airdropGrantRecordExportListVO.getTypeClassify().getDescription());
        });
        return airdropGrantRecordExportListVOS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void airdropGrant(String userIds, Long productId, Integer grantNum) throws GlobalException {
        DigitalCollectionProductInfo digitalCollectionProductInfo = digitalCollectionProductInfoDao.getairdropProduct(productId);
        if (grantNum>10001) {
            throw new GlobalException("最大数量10000个");
        }
        if (ObjectUtil.isEmpty(digitalCollectionProductInfo)) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        if (digitalCollectionProductInfo.getIsSoldOut()) {
            throw new GlobalRunTimeException(ErrorCode.COLLECTION_IS_SOLD_OUT);
        }
        ProductStock productStock = productStockService.getProductStock(productId, digitalCollectionProductInfo.getRelationId(), null);
        List<String> userList = Arrays.asList(userIds.split(","));
        if (userList.size()*grantNum>productStock.getUsableCount()){
            throw  new GlobalRunTimeException(ErrorCode.COUNT_NOT_ENOUGH);
        }
        for (String user : userList) {
            Long userId=Long.parseLong(user);
            airdropGrant(userId,productId,digitalCollectionProductInfo,grantNum);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchAirdropGrant(List<Map> list, Long productId,Integer grantNum) throws IOException, GlobalException {
        DigitalCollectionProductInfo digitalCollectionProductInfo = digitalCollectionProductInfoDao.getairdropProduct(productId);
        if (ObjectUtil.isEmpty(digitalCollectionProductInfo) ) {
            throw new GlobalRunTimeException(ErrorCode.PRODUCT_HAS_BEEN_DESCONTINUED);
        }
        if (digitalCollectionProductInfo.getIsSoldOut()) {
            throw new GlobalRunTimeException(ErrorCode.COLLECTION_IS_SOLD_OUT);
        }
        ProductStock productStock = productStockService.getProductStock(productId, digitalCollectionProductInfo.getRelationId(), null);
        Integer productStockSum=0;
        // 获取用户要发放的商品总数.
        for (Map map : list) {
            Integer num = Convert.toInt(map.get("num"));
            productStockSum+=num;
        }
        if (productStockSum>productStock.getUsableCount()){
            throw  new GlobalRunTimeException(ErrorCode.COUNT_NOT_ENOUGH);
        }
        for (Map map : list) {
            Long userId=Long.parseLong(map.get("id").toString());
            Integer num=Convert.toInt(map.get("num").toString());
            airdropGrant(userId,productId,digitalCollectionProductInfo,num);
        }
    }

    @Override
    public AirdropUserListVO upLoadAirdropUserExcel(MultipartFile uploadFile) throws IOException {
        List list=new ArrayList();
        String fileName = uploadFile.getOriginalFilename();
        String substring = fileName.substring(fileName.lastIndexOf("."));
        InputStream inputStream = uploadFile.getInputStream();
        Workbook wb = null;
        if(".xls".equals(substring)){
            wb = new HSSFWorkbook(inputStream);
        }else if(".xlsx".equals(substring)){
            wb = new XSSFWorkbook(inputStream);
        }else {
            throw  new GlobalRunTimeException(ErrorCode.WRONG_FILE_TYPE);
        }
        Sheet sheet = wb.getSheetAt(0);
        //获取最大行数
        int rownum = sheet.getPhysicalNumberOfRows();
        AirdropUserListVO airdropUserListVO=new AirdropUserListVO();
        Boolean smFlag=false;
        Boolean isExists=false;
        for (int i = 1; i <rownum ; i++) {
            Row row = sheet.getRow(i);
            Cell cell = row.getCell(0);
            Cell cell1 = row.getCell(1);
            cell.setCellType(CellType.STRING);
            cell1.setCellType(CellType.STRING);
            if (ObjectUtil.isNotEmpty(cell)){
                AirdropUserVO airdropUserVO=new AirdropUserVO();
                String userTel = cell.getStringCellValue().trim();
                String num = cell1.getStringCellValue().trim();
                UserInfo oneByUserTel = userInfoDao.getOneByUserTel(userTel);
                airdropUserVO.setUserTel(userTel);
                airdropUserVO.setNum(Convert.toInt(num));
                if (ObjectUtil.isEmpty(oneByUserTel)){
                    list.add(0,airdropUserVO);
                    isExists=false;
                }else{
                    airdropUserVO.setUuid(oneByUserTel.getUserUuid());
                    airdropUserVO.setId(oneByUserTel.getId());
                    airdropUserVO.setIsSm(oneByUserTel.getIsSm());
                    //已经发放过的空投个数
                    Integer count= airdropGrantRecordDao.getCountByUserId(oneByUserTel.getId());
                    airdropUserVO.setHaveNum(count);
                    if (!oneByUserTel.getIsSm()){
                        smFlag=true;
                    }
                    list.add(airdropUserVO);
                }
            }
        }
        airdropUserListVO.setIsSm(smFlag);
        airdropUserListVO.setIsExists(Boolean.TRUE);
        airdropUserListVO.setList(list);
        airdropUserListVO.setTotalNum(list.size());

        return airdropUserListVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void distributeEquityProps(Long userId, EquityProps equityProps, Integer num) {

        UserInfo user = userInfoDao.getById(userId);
        if(ObjectUtil.isNull(user)){
            throw new GlobalRunTimeException("用户不存在");
        }
        userEquityPropsService.addEquityPropsByUser(equityProps,userId, UserEquityPropsGetTypeEnum.AIRDROP,num,"空投发放",0L, BigDecimal.ZERO,UserEquityPropsGetTypeEnum.AIRDROP,0L);
        AirdropGrantRecord airdropGrantRecord = new AirdropGrantRecord();
        airdropGrantRecord.setUserId(user.getId());
        airdropGrantRecord.setProductId(equityProps.getId());
        airdropGrantRecord.setGrantNum(num);
        airdropGrantRecord.setType(AirdropGrantTypeEnum.EQUITY_PROPS);
        airdropGrantRecord.insert();
    }

    @Override
    public Page<AirdropGrantEquityPropsRecordVO> airdropGrantEquityPropsRecordList(Integer pageNo, Integer pageSize, String nickName, String userTel,  String firstTitle, Integer typeClassify) {
        return airdropGrantRecordDao.airdropGrantEquityPropsRecordList(new Page<>(pageNo,pageSize),nickName,userTel,firstTitle,typeClassify);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchAirdropGrantEquityProps(List<Map> list, Long productId) {
        EquityProps equityProps = equityPropsService.getById(productId);
        if(ObjectUtil.isNull(equityProps)){
            throw new GlobalRunTimeException("权益道具不存在");
        }

        for (Map map : list) {
            Integer num = Convert.toInt(map.get("num"));
            Long userId = Convert.toLong(map.get("id"));
            distributeEquityProps(userId,equityProps,num);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void airdropGrant(Long userId, Long productId, DigitalCollectionProductInfo digitalCollectionProductInfo, Integer grantNum) throws GlobalException {
        boolean isOpen = false;
        Long boxId = null;
        String boxTitle = null;
        String boxImage = null;
        Long collectionId = null;
        BoxItem boxItem = null;
        //如果兑换的是盲盒
        switch (digitalCollectionProductInfo.getTypeClassify()) {
            case COLLECTION:
                isOpen = true;
                collectionId = digitalCollectionProductInfo.getRelationId();
                break;
            case BLIND_BOX:
                boxItem = boxItemService.openBox(productId, digitalCollectionProductInfo.getRelationId());
                collectionId = boxItem.getCollectionId();
                BoxProduct boxProduct = boxProductDao.getById(digitalCollectionProductInfo.getRelationId());
                boxId= boxProduct.getId();
                boxTitle = boxProduct.getFirstTitle();
                boxImage= digitalCollectionProductInfo.getCreationContent();
                isOpen = false;
        }
        DigitalCollection digitalCollection = digitalCollectionDao.getById(collectionId);
        for (int i = 0; i < grantNum; i++) {
            //减去商品库存
            productStockService.subIntegralStock(productId, digitalCollectionProductInfo.getRelationId(), null, 1, userId, CommodityType.INTEGRAL_PRODUCT);
            switch (digitalCollectionProductInfo.getTypeClassify()) {
                case BLIND_BOX:
                    //减去盲盒库存
                    productStockService.subIntegralStock(productId, digitalCollectionProductInfo.getRelationId(), boxItem.getId(), 1, userId, CommodityType.AIR_DROP);
            }
            UserCollection userCollection = userCollectionService.addCollection(userId,null,digitalCollection.getId(), IdUtil.getSnowflakeNextIdStr(),digitalCollection.getCreationContent(),digitalCollection.getLevel(),digitalCollection.getFirstTitle(),
                    digitalCollection.getUserCreatorId(),ReceivedCollectionType.AIRDROP,boxId,boxTitle,boxImage,isOpen,productId,0L,0L,digitalCollectionProductInfo.getProductNum(),0,null,null,AddCollectionEnum.STAIR,null,null,false);

            AirdropGrantRecord airdropGrantRecord=new AirdropGrantRecord();
            airdropGrantRecord.setUserId(userId);
            airdropGrantRecord.setProductId(productId);
            airdropGrantRecord.setGrantNum(1);
            airdropGrantRecord.setUserCollectionId(userCollection.getId());
            airdropGrantRecord.setCollectionUuid(userCollection.getCollectionUuid());
            airdropGrantRecord.insert();
            //插入藏品流转记录
            CollectionCirculatingRecord collectionCirculatingRecord = new CollectionCirculatingRecord();
            collectionCirculatingRecord.setCommodityType(CommodityType.AIR_DROP);
            collectionCirculatingRecord.setTypeClassify(digitalCollectionProductInfo.getTypeClassify());
            collectionCirculatingRecord.setUserId(userId);
            collectionCirculatingRecord.setCollectionId(digitalCollection.getId());
            collectionCirculatingRecord.setReceivedCollectionType(ReceivedCollectionType.AIRDROP);
            collectionCirculatingRecord.setAirdropGrantRecordId(airdropGrantRecord.getId());
            collectionCirculatingRecord.insert();
        }
        if(digitalCollectionProductInfo.getTypeClassify()==ClassifyType.COLLECTION&&digitalCollection.getCollectionType()==DigitalMarketTypeEnum.ECOLOGY) {
                userConsensusService.adjustConsensusService(userId, digitalCollection.getId() ,BigDecimal.valueOf(grantNum), UserConsensusTypeEnums.AIR_DROP, digitalCollection.getFirstTitle(), null);
        }

    }

}